/***************************************************************************************************
  *Copyright(C),2010-2017,Sumscope
  *FileName	:  pinyin_search_idvec.h
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2017/06/04
  *Desc		:  //用于主要说明此程序文件完成的主要功能
  *Relation :  
  *Others	:  //其他内容说明
  *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
  *History	:  //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
***************************************************************************************************/
#pragma once

#include "pinyin_search_define.h"
#include "pinyin_search_set.h"
#include "../../core.h"

namespace qb{
	namespace base{

		namespace internal{
			class 		IndexIdStore;
            class S_CORE_EXPORT IndexIdVec {
				typedef unsigned int uint;
				typedef uint KeyType;
				typedef uint CountType;
				typedef IndexIdVec Base;
				IndexId*		m_first;			// 按照bid递增
				int				m_count;			// 个数
				int				m_capcity;			// 容量
				//IndexIdStore*	m_store;
			public:
				class const_iterator{
					int	m_index;
					const Base* m_owner;
				public:
					KeyType	first;
					CountType	second;
				public:
					explicit const_iterator(const Base* owner, int index){ m_owner = owner; m_index = index; owner->get(index, first, second); }
					const_iterator(const const_iterator& it) :m_owner(it.m_owner), m_index(it.m_index), first(it.first), second(it.second){}
					const_iterator& operator++(){ m_index++; m_owner->get(m_index, first, second); return *this; }
					bool operator!=(const const_iterator& ci)const{ return m_owner != ci.m_owner || m_index != ci.m_index; }
					const_iterator* operator->(){ return this; }
				};
			public:
				IndexIdVec();
				IndexIdVec(IndexId* first, int count, int capcity);

				void bind(IndexId* first, int count, int capcity);
				void copyfrom(const IndexIdVec& iivec);
				void copyfrom(const InverseSet& iset);
				void copyto(InverseSet& iset);
				bool equal(const InverseSet& iset)const;
				~IndexIdVec();
				int size()const{ return m_count; }
				IndexId at(int i)const{ return m_first[i]; }
				bool add(int key);
				void remove(int key);
				bool exist(int key)const;
				void clear();
				void intersect(const InverseSet& iset);
				void intersect(const IndexIdVec& iis);
				void intersect_old(const IndexIdVec& iis);
				bool empty()const{ return m_count <= 0; }
				const IndexId* first()const{ return m_first; }
				int count()const{ return m_count; }
				void transform();

				bool get(int index, KeyType& key, CountType& val) const;
				const_iterator cbegin()const{ return const_iterator(this, 0); }
				const_iterator cend()const{ return const_iterator(this, m_count); }
			protected:
				inline int find_fast(int key, int npos)const
				{
					if (npos < 0 || m_first == nullptr || npos >= m_count)
						return m_count;
					if (key <= spell::getkey(m_first[npos]))
						return npos;
					if (m_count >= 1)
					{
						int last = spell::getkey(m_first[m_count - 1]);
						if (key > last)return m_count;
						if (key == last)return m_count - 1;
					}
					return -1;
				}
				int find_slow(int key, int npos) const;
				int find(int key)const;
				int find_after(int key, int npos) const;
				int find_slow2(int key, int npos) const;
				int find_after_old(int key, int npos) const;
				void check();
			};

		}
	}
}
